﻿using System;
using System.Collections.Generic;

namespace Program_FlightChess
{
    class Program
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("----------------我也不知道叫啥好飞行棋----------------");
            Console.WriteLine("---------------------版本1.0.0------------------------");
            Console.WriteLine("------------------建议您使用全屏游玩------------------" + "\n" + "\n" + "\n");
            Console.ForegroundColor = ConsoleColor.Yellow;

            ChessBuild cb = new ChessBuild();
            while (!cb.isWin) 
            {
            Console.ReadLine();
            string message = cb.ChessBoardPrint();
            Console.WriteLine("\n" + message +"\n");
            }
        }
    }

    #region 棋盘逻辑
    class ChessBuild
    {
        #region 棋盘对象
        public string chessString = "□";
        public int ChessBoardLength = 90;
        public bool isWin = false;
        ChessBoard cb;
        #endregion

        #region 玩家对象
        Player player;
        string PlayerName = "Komeiji";
        Player bot1;
        Player bot2;
        List<Player> players;
        int playerTempCount = 0;    
        #endregion

        #region 棋盘事件对象
        List<ChessBoardAction> cbaList;
        string cbEventMessage = "";
        ChessBoardAction Boom;
        public string boomString = "☆";
        public const int boomCount = 3;
        public int[] boomIndexArr;

        ChessBoardAction Lucky;
        public string luckyString = "◎";
        public const int luckyCount = 6;
        public int[] luckyIndexArr;

        ChessBoardAction Stop;
        public string stopString = "▲";
        public const int stopCount = 3;
        public int[] stopIndexArr;

        ChessBoardAction Tunnel;
        public string tunnelString = "卐";
        public const int tunnelCount = 4;
        public int[] tunnelIndexArr;

        ChessBoardAction PlayerWin;
        #endregion

        /// <summary>
        /// 构造函数，用于初始化对象
        /// </summary>
        public ChessBuild()
        {
            #region 棋盘对象初始化
            cb = new ChessBoard(chessString, ChessBoardLength);
            #endregion

            #region 玩家对象初始化
            player = new Player(PlayerName, "");
            player.PlayerIndex = 0;
            bot1 = new Player("波特", "");
            bot1.PlayerIndex = 0;


            players = new List<Player>();
            players.Add(player);
            players.Add(bot1);
            //players.Add(bot2);
         
            #endregion

            #region 棋盘事件对象初始化
            cbaList = new List<ChessBoardAction>();

            PlayerWin = new ChessBoardAction("", null);
            PlayerWin.OnTrigger += OnPlayerWinEvent;

            boomIndexArr = new int[] { 6, 46, 71 };
            Boom = new ChessBoardAction(boomString, boomIndexArr);
            Boom.OnTrigger += OnBoomEvent;
            cbaList.Add(Boom);

            //luckyIndexArr = new int[] { 3, 13, 18, 51, 69, 88 };
            luckyIndexArr = new int[] { 88 };
            Lucky = new ChessBoardAction(luckyString, luckyIndexArr);
            Lucky.OnTrigger += OnLuckyEvent;
            cbaList.Add(Lucky);

            stopIndexArr = new int[] { 20, 38, 75, 2, 4, 5 };
            Stop = new ChessBoardAction(stopString, stopIndexArr);
            Stop.OnTrigger += OnStopEvent;
            cbaList.Add(Stop);

            tunnelIndexArr = new int[] { 24, 44, 65, 78 };
            Tunnel = new ChessBoardAction(tunnelString, tunnelIndexArr);
            Tunnel.OnTrigger += OnTunnelEvent;
            cbaList.Add(Tunnel);
            #endregion

            foreach (var item in cbaList)//替换地图字符串
            {
                foreach (var cba in item.chessBoardIndex)
                {
                    cb.chessMap[cba] = item.ActionString[0];
                }
            }
        }

        /// <summary>
        /// 输出整个棋盘的函数，这个程序的核心
        /// </summary>
        /// <returns></returns>
        public string ChessBoardPrint()
        {
            string Message = "";//棋盘信息

            if(isWin == false)//判断是否胜利
            {

            #region 棋盘打印
            Console.Clear();
            for (int i = 0; i < ChessBoardLength; i++)
            {              
                #region 棋盘颜色处理            
                    foreach (var item in cbaList)
                    {
                        foreach (var pla in players)
                        {
                            if (pla.PlayerIndex == i)
                            {
                                Console.ForegroundColor = ConsoleColor.Blue;
                            }
                            if(pla.PlayerIndex == i && pla.playerName != PlayerName)
                            {
                                Console.ForegroundColor = ConsoleColor.Magenta;
                            }
                        }

                        
                        if (item.actionName == boomString)
                        {
                            foreach (var item1 in item.chessBoardIndex)
                            {
                                if (i == item1)
                                {
                                    Console.ForegroundColor = ConsoleColor.Gray;
                                }
                            }
                        }
                        else if (item.actionName == luckyString)
                        {
                            foreach (var item1 in item.chessBoardIndex)
                            {
                                if (i == item1)
                                {
                                    Console.ForegroundColor = ConsoleColor.Green;
                                }
                            }
                        }
                        else if (item.actionName == stopString)
                        {
                            foreach (var item1 in item.chessBoardIndex)
                            {
                                if (i == item1)
                                {
                                    Console.ForegroundColor = ConsoleColor.Red;
                                }
                            }
                        }
                        else if (item.actionName == tunnelString)
                        {
                            foreach (var item1 in item.chessBoardIndex)
                            {
                                if (i == item1)
                                {
                                    Console.ForegroundColor = ConsoleColor.White;
                                }
                            }
                        }

                    }
             
                #endregion

                #region 棋盘打印图形
                if (i > (ChessBoardLength / 2))
                {
                    if (i == (ChessBoardLength / 2))
                    {
                        for (int x = 0; x < (ChessBoardLength / 3); x++)
                        {
                            Console.Write("  ");
                        }
                    }
                    Console.Write(cb.chessMap[i]);
                }
                else if (i > (ChessBoardLength / 3))
                {
                    Console.WriteLine();
                    for (int x = 0; x < (ChessBoardLength / 3); x++)
                    {
                        Console.Write("  ");
                    }
                    Console.Write(cb.chessMap[i]);
                }
                else
                {
                    Console.Write(cb.chessMap[i]);
                }
                #endregion

                Console.ForegroundColor = ConsoleColor.Yellow;
            }
            #endregion

            }
            Console.WriteLine("\n");
            Message += PlayerBehavior();//调用玩家逻辑函数     
            return Message;
        }

        #region 玩家逻辑

        /// <summary>
        /// 玩家行为函数，负责玩家的行动逻辑
        /// </summary>
        /// <returns>返回玩家行动信息</returns>
        public string PlayerBehavior() 
        {
            string playerMessage = "";
         

            if (players[playerTempCount].playerState == Player.PlayerState.move)
            {
                playerMessage += PlayerMove(players[playerTempCount]);
                Console.WriteLine(players[playerTempCount].playerName + "请输入任意键掷出骰子");
                Console.ReadLine();
                foreach (var item in cbaList)
                {
                    foreach (var item1 in item.chessBoardIndex)
                    {
                        if (players[playerTempCount].PlayerIndex == item1) 
                        {
                            item.OnTrigger(players[playerTempCount]);
                            playerMessage += cbEventMessage;
                            cbEventMessage = "";
                        }
                    }
                }
            }

            else 
            {
                Console.WriteLine(players[playerTempCount].playerName + "在空间与时间中模糊了自己的存在");                
                players[playerTempCount].playerState = Player.PlayerState.move;
                
                playerMessage += cbEventMessage;
                cbEventMessage = "";
            }

            if (playerTempCount < players.Count-1)
            {
                playerTempCount++;
            }
            else if (playerTempCount == players.Count-1) 
            {
                playerTempCount = 0;
            }
            foreach (var item in players)
            {
                if (item.PlayerIndex > ChessBoardLength)
                {
                    PlayerWin.OnTrigger(item);
                    return "";
                }

            }
            return playerMessage;
        }
        public int Dice()
        {
            return new Random().Next(1, 7);
        }
        public string PlayerMove(Player player) 
        {
            int i = Dice();
            player.PlayerIndex += i;
            return "\n"+"玩家" + player.playerName + "掷出了骰子"+"\n" + "移动了 " + i + " 格" + "\n";
        }
        #endregion

        #region 事件
        void OnPlayerWinEvent(Player ePlayer) 
        {
            isWin = true;
            Console.Clear();
            string winMessage = ePlayer.playerName + " 取得了胜利!";
            foreach (var item in winMessage)
            {
                Console.Write(item);                    
                System.Threading.Thread.Sleep(100);
            }
            Console.ReadLine();
        }
        void OnBoomEvent(Player ePlayer) 
        {
            ePlayer.MoveBack(6);
            cbEventMessage = "玩家" + ePlayer.playerName + "踩到到了炸弹，炸弹炸了，后退6格";
        }
        void OnLuckyEvent(Player ePlayer)
        {
            cbEventMessage = "玩家" + ePlayer.playerName + "遇到了幸运轮盘事件";
            int i = 0;
            Console.WriteLine("\n"+ "\n" + "玩家" + ePlayer.playerName + "拿到了幸运轮盘");
            Console.ReadLine();
            Console.WriteLine("请输入1或者2,1为选择一个对手交换位置,2为选择一个对手后退六格");
            while (!int.TryParse(Console.ReadLine(), out i))
            {
                Console.WriteLine("请输入1或2");
            }
            if (i == 1)
            {
                Console.Write("\n"+"请输入对手的Name(");
                foreach (var item in players)
                {
                    Console.Write(" " + item.playerName + " ");
                }
                Console.Write(")" + "\n");

                bool isBreak = false;
                string luckyBoy = Console.ReadLine();
                while (!isBreak)
                {
                    foreach (var item in players)
                    {
                        if (luckyBoy == item.playerName && luckyBoy != ePlayer.playerName)
                        {
                            int indextemp;
                            indextemp = ePlayer.PlayerIndex;
                            ePlayer.PlayerIndex = item.PlayerIndex;
                            item.PlayerIndex = indextemp;
                            Console.WriteLine("幸运儿 " + item.playerName + " 与玩家" + ePlayer.playerName + " 交换了位置");
                            isBreak = true;
                            break;
                        }
                        else if (luckyBoy == ePlayer.playerName)
                        {
                            Console.WriteLine("我换我自己？行吧");
                            Console.ReadLine();
                            Console.WriteLine("幸运儿 " + ePlayer.playerName + " 与玩家" + ePlayer.playerName + " 交换了位置");
                            isBreak = true;
                            break;
                        }
                    }
                }
            }
            else if (i == 2)
            {
                Console.WriteLine("请输入对手的Name(");
                foreach (var item in players)
                {
                    Console.Write(" " + item.playerName + " ");
                }
                Console.Write(")" + "\n");

                bool isBreak = false;
                string luckyBoy = Console.ReadLine();
                while (!isBreak)
                {
                    foreach (var item in players)
                    {
                        if (luckyBoy == item.playerName && luckyBoy != ePlayer.playerName)
                        {
                            item.MoveBack(6);
                            Console.WriteLine("幸运儿 " + item.playerName +" 后退了6格");
                            isBreak = true;
                            break;
                        }
                        else if (luckyBoy == ePlayer.playerName)
                        {
                            Console.WriteLine("噢，你可真是个带慈善家，行吧！");
                            Console.ReadLine();
                            Console.WriteLine("玩家" + ePlayer.playerName + " 后退了六格");
                            Console.WriteLine("玩家" + ePlayer.playerName + " 获得了称号“慈善家”");
                            isBreak = true;
                            break;
                        }
                    }
                }
            }
        }
        void OnTunnelEvent(Player ePlayer) 
        {

            ePlayer.MoveFront(10);
            cbEventMessage = "玩家" + ePlayer.playerName + "进入了时刻隧道，前进10格";
        }
        void OnStopEvent(Player ePlayer)      
        {
            ePlayer.playerState = Player.PlayerState.stop;
            cbEventMessage = "玩家" + ePlayer.playerName + "被停止了时间,暂停一回合";
        }
        #endregion
    }
    #endregion

    #region 玩家类
    class Player
    {      
        public enum PlayerState
        {
            stop = 1,
            move = 0
        }

        public string playerName { get; }
        public string playerString { get; }
       

        public PlayerState playerState = 0;

        private int playerIndex = 0;
        public int PlayerIndex { get => playerIndex; set{ if (value < 0) value = 0; else playerIndex = value; } }
        
public Player(string playerName,string playerString) //初始化玩家属性
        {
            this.playerName = playerName;
            this.playerString = playerString;
        }
        public void MoveFront(int count) 
        {
            PlayerIndex += count;
        }
        public void MoveBack(int count) 
        {
            PlayerIndex -= count;
        }
    }
    #endregion

    #region 棋盘类
    class ChessBoard
    {
        public List<string> chessMap;
        int length { get; }

        /// <summary>
        /// 棋盘格类
        /// </summary>
        /// <param name="chessString">棋格的字符图形</param>
        /// <param name="length">棋盘的格数(长度)</param>
        public ChessBoard(string chessString, int length) 
        {
            chessMap = new List<string>();
            this.length = length;

            for (int i = 0; i < length; i++)
            {
                chessMap.Add(chessString);
            }
        }
    }
    #endregion

    #region 棋盘事件类
    class ChessBoardAction
    {
        /// <summary>
        /// 棋盘事件类
        /// </summary>
        public Action<Player> OnTrigger;

        public string actionName;

        public List<string> ActionString;
        public int count { get; }
        public int[] chessBoardIndex { get; }

        public ChessBoardAction(string chessString,int []chessBoardIndex)
        {
            actionName = chessString;
            if (chessBoardIndex != null)
            {
                count = chessBoardIndex.Length;
                this.chessBoardIndex = chessBoardIndex;
                ActionString = new List<string>();
                for (int i = 0; i < count; i++)
                {
                    ActionString.Add(chessString);
                }
            }
        }
    }
    #endregion
}
